﻿using System;
using System.Collections.Generic;
using GameFramework.Battle.Core;
using Gameplay.PVE.Utils;
using RootMotion.FinalIK;
using UnityEngine;

namespace Gameplay.PVE.Survivor
{
    public class SpecialParabolaMovement : BulletMovement
    {
        private float moveTime;
        private Vector3 startPosition;
        private Vector3 targetPosition;
        private float startTime;

        private Vector3 velocity;
        private Vector3 velocityHorizontal;
        private float velocityHorizontalValue;
        private Vector3 velocityVertical;
        
        private const float gravity = 9.8f;
        private Vector3 position;

        private int fixedFlyFrame;
        private float fixedFlyTime;
        private int secondBulletId;
        private int secondBulletDelayFrame;
        private float secondBulletTime;
        private int secondBulletIndex;
        private bool secondBulletStart;
        private float boomHeight;
        
        private Bullet secondBullet;

        private float destroyTime;
        
        public override void Start()
        {
            isFinish = false;
            startPosition = bullet.Position;
            targetPosition = bullet.targetPosition;

            startTime = TimeManager.time;
            
            fixedFlyFrame = (int)bullet.config.GetParamInt("flyFrame");
            fixedFlyTime = fixedFlyFrame / 30f;
            secondBulletId = (int)bullet.config.GetParamInt("secondBullet");
            secondBulletDelayFrame = (int)bullet.config.GetParamInt("secondBulletDelayFrame");
            secondBulletTime = secondBulletDelayFrame / 30f + bullet.sourceSpawner.startTime;
            secondBulletIndex = (int)bullet.config.GetParamInt("secondBulletIndex");
            secondBulletStart = false;
            boomHeight = bullet.config.GetParam("height");

            var xDiff = targetPosition.x - startPosition.x;
            var zDiff = targetPosition.z - startPosition.z;
            var horizontalDistance = Mathf.Sqrt(xDiff * xDiff + zDiff * zDiff);
            var horizontalSpeed = horizontalDistance / fixedFlyTime;

            var startHeight = startPosition.y;
            var endHeight = this.boomHeight;
            var upTime = (endHeight - startHeight + 0.5f * gravity * fixedFlyTime * fixedFlyTime) / (gravity * fixedFlyTime);
            var verticalSpeed = gravity * upTime;

            velocityHorizontalValue = horizontalSpeed;
            velocity = horizontalSpeed * new Vector3(xDiff, 0, zDiff).normalized + verticalSpeed * Vector3.up;
            position = startPosition;
        }
        
        public override void Update()
        {
            velocity -= new Vector3(0, gravity, 0) * Time.deltaTime;
            position = position + velocity * Time.deltaTime;
            if (!secondBulletStart && TimeManager.time >= secondBulletTime)
            {
                //出发子子弹
                secondBulletStart = true;
                var config = BattleConfigManager.Instance.GetBulletConfig(secondBulletId);
                secondBullet = BulletManager.Instance.CreateBullet(config);
                var startPosition = bullet.sourceUnit.GetGunPoint(secondBulletIndex).position;
                var targetPosition = this.targetPosition + new Vector3(0, boomHeight, 0);
                secondBullet.SetTargetPosition(targetPosition);
               
                var currentPos = new Vector3(position.x, 0, position.z);
                var targetPos = new Vector3(targetPosition.x, 0, targetPosition.z);
                var distance = Vector3.Distance(currentPos, targetPos);
                var time = distance / velocityHorizontalValue;
                distance = Vector3.Distance(startPosition, targetPosition);
                secondBullet.SetExternalSpeed(distance / time);
                secondBullet.Initialize(config, bullet.sourceSpawner, bullet.sourceUnit);
                secondBullet.SetStartPosition(startPosition);
                secondBullet.Start();
                destroyTime = TimeManager.time + time;
            }
            
            if (velocity.y < 0 && (position.y <= boomHeight || TimeManager.time >= destroyTime))
            {
                isFinish = true;
                position.y = boomHeight;
                bullet.Position = position;
                bullet.Forward = new Vector3(bullet.Forward.x,0,bullet.Forward.z);
                bullet.HitByCollision();
                return;
            }
            bullet.Position = position;
        }

        public override bool IsEnd()
        {
            return isFinish;
        }
    }
}
